package org.jeecg.modules.lottery.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jeecg.modules.lottery.entity.LotteryManagement;
import org.jeecg.modules.lottery.mapper.LotteryManagementMapper;
import org.jeecg.modules.lottery.service.ILotteryManagementService;
import org.jeecg.modules.lottery.service.ILotteryService;
import org.jeecg.modules.purchase.entity.PurchasePlan;
import org.jeecg.modules.purchase.service.IPurchasePlanService;
import org.jeecg.modules.supplier.entity.Supplier;
import org.jeecg.modules.supplier.service.ISupplierService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@Service
@Slf4j
public class LotteryManagementServiceImpl extends ServiceImpl<LotteryManagementMapper, LotteryManagement> implements ILotteryManagementService {
    @Autowired
    private IPurchasePlanService purchasePlanService;

    @Autowired
    private ISupplierService supplierService;

    @Autowired
    private ILotteryService lotteryService;

//    @Override
//    public void add2(int eligibleSuppliers ,String purchaseId, String category, int drawCount, String admin) {
//        PurchasePlan purchasePlan = purchasePlanService.getById(purchaseId);
//        String winningSupplierNames = lotteryService.getWinningSupplierNamesByPurchaseId(purchaseId);
//        LotteryManagement lotteryManagement = new LotteryManagement();
//        lotteryManagement.setPurchaseId(purchaseId);
//        lotteryManagement.setProjectName(purchasePlan.getProjectName());
//        lotteryManagement.setDrawQuantity(drawCount);//中签个数
//        lotteryManagement.setDrawPerson(admin);//抽签人
//        lotteryManagement.setDrawTime(new Date());
//        lotteryManagement.setStatus("1");
//        lotteryManagement.setCategory(category);
//        lotteryManagement.setParticipantCount(eligibleSuppliers);
//        lotteryManagement.setDrawRule("随机抽签，公平公正");
//        lotteryManagement.setWinningSuppliers(winningSupplierNames);
//        this.save(lotteryManagement);
//    }

    @Override
    public void add(String purchaseId,String category) {
        // 根据purchaseId获取采购方案信息
        if (purchaseId != null) {
            PurchasePlan purchasePlan = purchasePlanService.getById(purchaseId);
            if (purchasePlan != null) {

                LotteryManagement lotteryManagement = new LotteryManagement();

                lotteryManagement.setPurchaseId(purchaseId);
                // 设置项目名称
                lotteryManagement.setProjectName(purchasePlan.getProjectName());
                List<Supplier> eligibleSuppliers = supplierService.getSuppliersForLottery(category);
                lotteryManagement.setParticipantCount(eligibleSuppliers.size());//参与抽签的供应商个数
                //TODO 抽签前要展示参与抽签的供应商吗？
                // 设置创建时间
                lotteryManagement.setCreateTime(new Date());
                lotteryManagement.setProjectNumber(purchasePlan.getProjectNumber());
                lotteryManagement.setBudgetAmount(purchasePlan.getBudgetAmount());
                lotteryManagement.setStatus("0");
                lotteryManagement.setCategory(category);
                lotteryManagement.setDrawRule("随机抽签，公平公正");
                // 保存到数据库
                this.save(lotteryManagement);
            }
        }

    }

    /**
     * 安全地获取单元格内容的字符串表示
     * 处理不同类型的单元格（数值、字符串等）
     */
    private String getCellStringValue(XSSFCell cell) {
        if (cell == null) {
            return "";
        }

        try {
            switch (cell.getCellType()) {
                case STRING:
                    return cell.getStringCellValue();
                case NUMERIC:
                    // 对于数值类型，转换为字符串
                    return String.valueOf(cell.getNumericCellValue());
                case BOOLEAN:
                    return String.valueOf(cell.getBooleanCellValue());
                case FORMULA:
                    return cell.getCellFormula();
                default:
                    return "";
            }
        } catch (Exception e) {
            log.error("获取单元格内容失败: " + e.getMessage(), e);
            return "";
        }
    }

    @Override
    public void exportExcelById(List<String> ids, HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {
            // 记录查询参数，用于调试
            log.info("导出Excel-根据ids查询抽签记录，ids: {}", ids);

            // 首先尝试使用QueryWrapper查询，确保精确匹配
            QueryWrapper<LotteryManagement> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("id", ids);
            List<LotteryManagement> lotteryManagementList = this.list(queryWrapper);

            // 如果QueryWrapper查询失败，尝试使用listByIds作为备选
            if (lotteryManagementList == null || lotteryManagementList.isEmpty()) {
                log.info("使用QueryWrapper查询未找到记录，尝试使用listByIds方法");
                lotteryManagementList = this.listByIds(ids);
            }

            // 记录查询结果
            if (lotteryManagementList == null) {
                log.warn("导出Excel-查询结果为null，ids: {}", ids);
                throw new RuntimeException("未找到对应的抽签记录");
            }
            if (lotteryManagementList.isEmpty()) {
                // 尝试逐个查询，确认哪些id存在问题
                for (String id : ids) {
                    LotteryManagement singleRecord  = this.getById(id);
                    log.info("单个id查询结果 - id: {}, 存在: {}", id, singleRecord != null);
                }
                log.warn("导出Excel-查询结果为空集合，ids: {}", ids);
                throw new RuntimeException("未找到对应的抽签记录");
            }
            log.info("导出Excel-查询成功，找到{}条记录", lotteryManagementList.size());

            // 创建Excel工作簿
            XSSFWorkbook workbook = new XSSFWorkbook();
            XSSFSheet sheet = workbook.createSheet("抽签记录");

            // 创建表头样式
            CellStyle headerStyle = workbook.createCellStyle();
            headerStyle.setAlignment(HorizontalAlignment.CENTER);
            headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerStyle.setFont(headerFont);

            // 创建内容样式
            CellStyle contentStyle = workbook.createCellStyle();
            contentStyle.setAlignment(HorizontalAlignment.LEFT);
            contentStyle.setVerticalAlignment(VerticalAlignment.CENTER);

            // 创建表头
            String[] headers = {"项目名称", "采购计划ID", "抽签类别", "参与供应商数量", "抽签数量", "抽签规则", "抽签人", "抽签时间", "状态", "中签供应商"};
            XSSFRow headerRow = sheet.createRow(0);
            for (int i = 0; i < headers.length; i++) {
                XSSFCell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
                sheet.autoSizeColumn(i);
            }

            // 填充数据
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for (int i = 0; i < lotteryManagementList.size(); i++) {
                LotteryManagement lotteryManagement = lotteryManagementList.get(i);
                XSSFRow row = sheet.createRow(i + 1);

                // 项目名称
                row.createCell(0).setCellValue(lotteryManagement.getProjectName() != null ? lotteryManagement.getProjectName() : "");
                // 采购计划ID
                row.createCell(1).setCellValue(lotteryManagement.getPurchaseId() != null ? lotteryManagement.getPurchaseId() : "");
                // 抽签类别
                row.createCell(2).setCellValue(lotteryManagement.getCategory() != null ? lotteryManagement.getCategory() : "");
                // 参与供应商数量
                Integer participantCount = lotteryManagement.getParticipantCount();
                row.createCell(3).setCellValue(participantCount != null ? participantCount : 0);
                // 抽签数量
                Integer drawQuantity = lotteryManagement.getDrawQuantity();
                row.createCell(4).setCellValue(drawQuantity != null ? drawQuantity : 0);
                // 抽签规则
                row.createCell(5).setCellValue(lotteryManagement.getDrawRule() != null ? lotteryManagement.getDrawRule() : "");
                // 抽签人
                row.createCell(6).setCellValue(lotteryManagement.getDrawPerson() != null ? lotteryManagement.getDrawPerson() : "");
                // 抽签时间
                row.createCell(7).setCellValue(lotteryManagement.getDrawTime() != null ? dateFormat.format(lotteryManagement.getDrawTime()) : "");
                // 状态
                String statusText = "";
                if ("0".equals(lotteryManagement.getStatus())) {
                    statusText = "未抽签";
                } else if ("1".equals(lotteryManagement.getStatus())) {
                    statusText = "已抽签";
                }
                row.createCell(8).setCellValue(statusText);
                // 中签供应商
                row.createCell(9).setCellValue(lotteryManagement.getWinningSuppliers() != null ? lotteryManagement.getWinningSuppliers() : "");

                // 设置内容行样式
                for (int j = 0; j < headers.length; j++) {
                    XSSFCell cell = row.getCell(j);
                    cell.setCellStyle(contentStyle);

                    // 自动调整列宽 - 安全处理不同类型的单元格
                    int currentWidth = sheet.getColumnWidth(j);
                    // 获取单元格内容的字符串表示，无论单元格类型如何
                    String cellValue = getCellStringValue(cell);
                    int newWidth = (int)((cellValue.length() + 2) * 256);
                    if (newWidth > currentWidth) {
                        sheet.setColumnWidth(j, newWidth);
                    }
                }
            }

            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            String fileName = "抽签记录_" + System.currentTimeMillis() + ".xlsx";

            // 改进文件名编码处理，兼容各种浏览器
            try {
                String userAgent = request.getHeader("User-Agent");
                if (userAgent != null) {
                    userAgent = userAgent.toLowerCase();
                    if (userAgent.contains("msie") || userAgent.contains("trident")) {
                        fileName = URLEncoder.encode(fileName, "UTF-8");
                    } else if (userAgent.contains("safari")) {
                        // Safari浏览器特殊处理
                        fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
                    } else {
                        // 其他现代浏览器
                        fileName = URLEncoder.encode(fileName, "UTF-8");
                    }
                } else {
                    fileName = URLEncoder.encode(fileName, "UTF-8");
                }
            } catch (Exception e) {
                log.error("文件名编码处理失败", e);
                fileName = "抽签记录.xlsx";
            }

            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ";filename*=UTF-8''" + fileName);
            response.setContentLengthLong(-1L); // 不设置具体长度，由容器处理

            // 确保响应头设置正确，在写入数据前再次确认
            response.resetBuffer(); // 重置缓冲区，确保没有其他数据
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ";filename*=UTF-8''" + fileName);
            response.setHeader("Pragma", "public");
            response.setHeader("Cache-Control", "max-age=0");

            // 输出Excel文件
            ServletOutputStream outputStream = null;
            try {
                outputStream = response.getOutputStream();

                // 使用字节数组缓存，确保完整写入
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                workbook.write(baos);
                byte[] bytes = baos.toByteArray();

                // 设置内容长度
                response.setContentLength(bytes.length);

                // 写入响应流
                outputStream.write(bytes);
                outputStream.flush();
                // 确保所有数据都写入客户端
                response.flushBuffer();

                log.info("Excel文件成功写入响应流，字节数: {}", bytes.length);
            } finally {
                // 确保工作簿和输出流都正确关闭
                if (workbook != null) {
                    try { workbook.close(); } catch (Exception e) { log.error("关闭工作簿失败", e); }
                }
                if (outputStream != null) {
                    try { outputStream.close(); } catch (Exception e) { log.error("关闭输出流失败", e); }
                }
            }

        } catch (Exception e) {
            log.error("导出Excel失败: " + e.getMessage(), e);
            throw new Exception("导出Excel失败: " + e.getMessage(), e);
        }
    }
}
